/* -*- mode: c++; coding: utf-8 -*- */

//     Ice adaptation of the OMG property service, downloaded from
//     ftp://ftp.omg.org/pub/docs/1995/95-06-01.ps
//
//     Code derived from TAO CosProperty.idl

#ifndef PROPERTY_SERVICE_ICE
#define PROPERTY_SERVICE_ICE

#include <PropertyType.ice>

module PropertyService {

    // = TITLE
    //     PropertyService : To support properties (that are typed
    //     named values dynamically associated with an object, outside
    //     of the type system.
    //
    // = DESCRIPTION
    //     The data types and interfaces to deal with property names,
    //     property values, property modes etc.

    // = Data Types.


    struct Property {
	string propertyName;
	P::T propertyValue;
    };

    enum PropertyModeType {
	normal,
	readOnly,
	fixedNormal,
	fixedReadonly,
	undefined
    };

    struct PropertyDef {
	P::T propertyValue;
	PropertyModeType propertyMode;
    };

    dictionary<string,P::T> Properties;
    dictionary<string,PropertyDef> PropertyDefs;
    dictionary<string,PropertyModeType> PropertyModes;

    interface PropertyNamesIterator;
    interface PropertiesIterator;
    interface PropertySetFactory;
    interface PropertySetDef;
    interface PropertySet;

    // = Exceptions

    exception ConstraintNotSupported {};
    exception InvalidPropertyName {};
    exception ConflictingProperty {};
    exception PropertyNotFound {};
    exception UnsupportedTypeCode {};
    exception UnsupportedProperty {};
    exception UnsupportedMode {};
    exception FixedProperty {};
    exception ReadOnlyProperty {};

    enum ExceptionReason {
	rInvalidPropertyName,
	rConflictingProperty,
	rPropertyNotFound,
	rUnsupportedTypeCode,
	rUnsupportedProperty,
	rUnsupportedMode,
	rFixedProperty,
	rReadOnlyProperty
    };

    struct PropertyException {
	ExceptionReason reason;
	string failingPropertyName;
    };

    sequence<PropertyException> PropertyExceptions;

    exception MultipleExceptions {
	PropertyExceptions exceptions;
    };

    // = Interface Definitions.

    interface PropertySetFactory {
	// = TITLE
	//     Factory class for PropertySet interface.
	// = DESCRIPTION
	//     Support for creating PropertySets with initial
	//     constraints and properties.

	PropertySet* createPropertySet ();
	// The createPropertySet operation returns a new
	// PropertySet. It is considered an implementation issue as to
	// whether the PropertySet contains any initial properties or
	// has constraints.

	PropertySet* createConstrainedPropertySet (/*PropertyTypes allowedPropertyTypes,*/
						  Properties allowedProperties)
	    throws ConstraintNotSupported;
	// The createConstrainedPropertySet operation allows a client
	// to create a new PropertySet with specific constraints.

	PropertySet* createInitialPropertySet (Properties initialProperties)
	    throws MultipleExceptions;
	// The createInitialPropertySet operation allows a client to
	// create a new PropertySet with specific initial properties.
    };

    interface PropertySetDefFactory {
	// = TITLE
	//     Factory class for PropertySetDef interface.
	// = DESCRIPTION
	//     Support for creating Propsetdefs with initial constraints
	//     and properties.

	PropertySetDef* createPropertySetDef ();
	//  The createPropertySetDef operation returns a new
	//  PropertySetDef.

	PropertySetDef* createConstrainedPropertySetDef (/*PropertyTypes allowedPropertyTypes,*/
                                                        PropertyDefs  allowedPropertyDefs)
	    throws ConstraintNotSupported;
	// The createConstrainedPropertySetDef operation allows a
	// client to create a new PropertySetDef with specific
	// constraints, including property modes.

	PropertySetDef* createInitialPropertySetDef (PropertyDefs initialPropertyDefs)
	    throws MultipleExceptions;
	// The createInitialPropertySetDef operation allows a client
	// to create a new PropertySetDef with specific initial
	// properties, including property modes.
    };

    interface PropertySet {
	// = TITLE
	//     The PropertySet interface provides operations to define
	//     and modify properties, list and get properties, and
	//     delete properties.
	//
	// = DESCRIPTION
	//     Provides support for defining and modifying properties,
	//     getting properties and their names and deleting properties.

	// = Support for defining and modifying properties.


	 void defineProperty (string theName,
			     P::T theValue)
	    throws InvalidPropertyName,
		    ConflictingProperty,
		    UnsupportedTypeCode,
		    UnsupportedProperty,
		    ReadOnlyProperty;
	// Will modify or add a property to the PropertySet. If the
	// property already exists, then the property type is checked
	// before the value is overwritten. If the property does not
	// exist, then the property is added to the PropertySet.

	 void defineProperties (Properties nproperties)
	    throws MultipleExceptions;
	// Will modify or add each of the properties in Properties
	// parameter to the PropertySet. For each property in the list,
	// if the property already exists, then the property type is
	// checked before overwriting the value. If the property does
	// not exist, then the property is added to the PropertySet.

	// = Support for Getting Properties and their Names.

	long getNumberOfProperties ();
	// Returns the current number of properties associated with this
	// PropertySet.

	void getAllPropertyNames (long howMany,
				  out Ice::StringSeq theNames,
				  out PropertyNamesIterator* rest);
	// Returns all of the property names currently defined in the
	// PropertySet. If the PropertySet contains more than howMany
	// property names, then the remaining property names are put
	// into the PropertyNamesIterator.

	P::T  getPropertyValue (string theName)
	    throws PropertyNotFound,
		    InvalidPropertyName;
	// Returns the value of a property in the PropertySet.

	bool getProperties (Ice::StringSeq theNames,
			    out Properties nproperties);
	// Returns the values of the properties listed in
	// propertyNames.

	void getAllProperties (long howMany,
                               out Properties nproperties,
                               out PropertiesIterator* rest);
	// Returns all of the property names currently defined in the
	// PropertySet. If the PropertySet contains more than howMany
	// property names, then the remaining property names are put
	// into the PropertyNamesIterator.

	// = Support for Deleting Properties.

	 void deleteProperty (string theName)
	    throws PropertyNotFound,
		    InvalidPropertyName,
		    FixedProperty;
	// Deletes the specified property if it exists from a
	// PropertySet.


	 void deleteProperties (Ice::StringSeq theNames)
	    throws MultipleExceptions;
	// Deletes the properties defined in the propertyNames
	// parameter. This is a batch operation that returns the
	// MultipleExceptions exception if any delete failed.

	 bool deleteAllProperties ();
	// Variation of deleteProperties. Applies to all properties.

	// = Support for Existence Check.

	bool isPropertyDefined (string theName)
	    throws InvalidPropertyName;
	// The isPropertyDefined operation returns true if the
	// property is defined in the PropertySet, and returns false
	// otherwise.
    };

    interface PropertySetDef extends PropertySet {
	// = TITLE
	//     Interface to deal with the Property Modes.
	//
	// = DESCRIPTION
	//     The PropertySetDef interface is a specialization
	//     (subclass) of the PropertySet interface. The
	//     PropertySetDef interface provides operations to retrieve
	//     PropertySet constraints, define and modify properties
	//     with modes, and to get or set property modes.

	/*void getAllowedPropertyTypes (out PropertyTypes propertyTypes);*/
	// Indicates which types of properties are supported by this
	// PropertySet. If the output sequence is empty, then there is
	// no restrictions on the any TypeCode portion of the
	// propertyValue field of a Property in this PropertySet,
	// unless the getAllowedProperties output sequence is not empty.

	void getAllowedProperties (out PropertyDefs allowedDefs);
	// Indicates which properties are supported by this
	// PropertySet. If the output sequence is empty, then there is
	// no restrictions on the properties that can be in this
	// PropertySet, unless the getAllowedPropertyTypes output
	// sequence is not empty.

	void definePropertyWithMode (string theName,
				     P::T theValue,
				     PropertyModeType theMode)
	    throws InvalidPropertyName,
		    ConflictingProperty,
		    UnsupportedTypeCode,
		    UnsupportedProperty,
		    UnsupportedMode,
		    ReadOnlyProperty;
	// This operation will modify or add a property to the
	// PropertySet. If the property already exists, then the
	// property type is checked before the value is overwritten. The
	// property mode is also checked to be sure a new value may be
	// written. If the property does not exist, then the property is
	// added to the PropertySet. To change the any TypeCode portion
	// of the propertyValue of a property, a client must first
	// deleteProperty, then invoke the definePropertyWithMode.

	 void definePropertiesWithModes (PropertyDefs theDefs)
	    throws MultipleExceptions;
	// This operation will modify or add each of the properties in
	// the Properties parameter to the PropertySet. For each
	// property in the list, if the property already exists, then
	// the property type is checked before overwriting the
	// value. The property mode is also checked to be sure a new
	// value may be written. If the property does not exist, then
	// the property is added to the PropertySet. This is a batch
	// operation that returns the MultipleExceptions exception if
	// any define operation failed.

	// = Support for Getting and Setting Property Modes.

	PropertyModeType getPropertyMode ( string theName)
	    throws PropertyNotFound,
		    InvalidPropertyName;
	// Support for Getting and Setting Property Modes.

	bool getPropertyModes (Ice::StringSeq theNames,
			       out PropertyModes theModes);
	// Support for Getting and Setting Property Modes.

	void setPropertyMode (string theName,
			      PropertyModeType theMode)
	    throws InvalidPropertyName,
		    PropertyNotFound,
		    UnsupportedMode;
	// Sets the mode of a property in the PropertySet.

	void setPropertyModes (PropertyModes theModes)
	    throws MultipleExceptions;
	// Sets the mode for each property in the propertyModes
	// parameter. This is a batch operation that returns the
	// MultipleExceptions exception if any set failed.

    };

    interface PropertyNamesIterator {
	// = TITLE
	//     Interface for iterating thru the Property Names.
	//
	// = DESCRIPTION
	//     The PropertyNamesIterator interface allows a client to
	//     iterate through the names using the nextOne or nextN operations.

	void reset ();
	// The reset operation resets the position in an iterator to the
	// first property, if one exists.

	bool nextOne (out string theName);
	// The nextOne operation returns true if an item exists at the
	// current position in the iterator with an output parameter of
	// a property name. A return of false signifies no more items in
	// the iterator.

	bool nextN (long howMany,
		    out Ice::StringSeq theNames);
	// The nextN operation returns true if an item exists at the
	// current position in the iterator and the howMany parameter
	// was set greater than zero. The output is a Ice::StringSeq
	// sequence with at most the howMany number of names. A return
	// of false signifies no more items in the iterator.

	void destroy ();
	// The destroy operation destroys the iterator.
    };

    interface PropertiesIterator {
	// = TITLE
	//     Interface for iterating thru the Properties.
	//
	// = DESCRIPTION
	//     allows a client to through the name-value pairs using the
	//     nextOne or nextN operations.

	void reset ();
	// The reset operation resets the position in an iterator to the
	// first property, if one exists.

	bool nextOne (out Property aProperty);
	// The nextOne operation returns true if an item exists at the
	// current position in the iterator with an output parameter of
	// a property. A return of false signifies no more items in the
	// iterator.

	bool nextN (long howMany,
		    out Properties nProperties);
	// The nextN operation returns true if an item exists at the
	// current position in the iterator and the howMany parameter
	// was set greater than zero. The output is a properties
	// sequence with at most the howMany number of properties. A
	// return of false signifies no more items in the iterator.

	void destroy ();
	// The destroy operation destroys the iterator.
    };
};

#endif
